package org.ghost.springboot.demo.service.impl;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.ghost.springboot.demo.entity.UserEntity;
import org.ghost.springboot.demo.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Primary
@Service
public class UserServiceImpl implements IUserService {
    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Override
    public boolean add(List<UserEntity> userEntityList) {
        if (CollectionUtils.isNotEmpty(userEntityList)) {
            //todo 之间这里不用写,根据主键生成器生成
            String sql = "INSERT INTO t_user(`username`,`age`,`sex`,`client_sn`) VALUES(:userName,:age,:sex,:clientSn)";
            int[] rows = namedParameterJdbcTemplate.batchUpdate(sql, userEntityList.stream().filter(Objects::nonNull).map(BeanPropertySqlParameterSource::new).toArray(SqlParameterSource[]::new));

            return ArrayUtils.isNotEmpty(rows);
        }
        return false;
    }

    @Override
    public boolean add(UserEntity userEntity) {
        if (userEntity != null) {
            //todo 之间这里不用写,根据主键生成器生成
            String sql = "INSERT INTO t_user(`username`,`age`,`sex`,`client_sn`) VALUES(:userName,:age,:sex,:clientSn)";
            int rows = namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(userEntity));

            return rows > 0;
        }
        return false;
    }

    @Override
    public boolean updateById(UserEntity userEntity, Long id) {
        if (userEntity != null && id != null) {
            String sql = "UPDATE t_user SET username=:userName,age=:age,sex=:sex WHERE id=:id";

            userEntity.setId(id);
            int rows = namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(userEntity));
            return rows > 0;
        }
        return false;
    }

    @Override
    public boolean updateByClientSn(UserEntity userEntity, Long clientSn) {
        if (userEntity != null && clientSn != null) {
            String sql = "UPDATE t_user SET username=:userName,age=:age,sex=:sex WHERE client_sn=:clientSn";

            userEntity.setClientSn(clientSn);
            int rows = namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(userEntity));

            return rows > 0;
        }
        return false;
    }

    @Override
    public boolean deleteById(Long id) {
        if (id != null) {
            Map<String, Object> paraMap = new HashMap<String, Object>();
            paraMap.put("id", id);

            String sql = "DELETE FROM t_user WHERE id=:id";
            int rows = namedParameterJdbcTemplate.update(sql, paraMap);

            return rows > 0;
        }
        return false;
    }

    @Override
    public boolean deleteByClientSn(Long clientSn) {
        if (clientSn != null) {
            Map<String, Object> paraMap = new HashMap<String, Object>();
            paraMap.put("clientSn", clientSn);

            String sql = "DELETE FROM t_user WHERE client_sn=:clientSn";
            int rows = namedParameterJdbcTemplate.update(sql, paraMap);

            return rows > 0;
        }
        return false;
    }

    @Override
    public UserEntity selectById(Long id) {
        if (id != null) {
            Map<String, Object> paraMap = new HashMap<String, Object>();
            paraMap.put("id", id);

            String sql = "SELECT tu.`id`,tu.`username` AS userName,tu.`age`,tu.`sex`,tu.`client_sn` AS clientSn FROM t_user AS tu WHERE 1=1 AND id=:id LIMIT 1";

            return namedParameterJdbcTemplate.query(sql, paraMap, new ResultSetExtractor<UserEntity>() {
                @Override
                public UserEntity extractData(ResultSet rs) throws SQLException, DataAccessException {
                    if (rs.next()) {
                        UserEntity userEntity = new UserEntity();
                        userEntity.setId(rs.getLong("id"));
                        userEntity.setAge(rs.getInt("age"));
                        userEntity.setClientSn(rs.getLong("clientSn"));
                        userEntity.setSex(rs.getString("sex"));
                        userEntity.setUserName(rs.getString("userName"));

                        return userEntity;
                    }
                    return null;
                }
            });
        }
        return null;
    }

    @Override
    public UserEntity selectByClientSn(Long clientSn) {
        if (clientSn != null) {
            Map<String, Object> paraMap = new HashMap<String, Object>();
            paraMap.put("clientSn", clientSn);

            String sql = "SELECT tu.`id`,tu.`username` AS userName,tu.`age`,tu.`sex`,tu.`client_sn` AS clientSn FROM t_user AS tu WHERE 1=1 AND tu.`client_sn`=:clientSn LIMIT 1";

            return namedParameterJdbcTemplate.query(sql, paraMap, new ResultSetExtractor<UserEntity>() {
                @Override
                public UserEntity extractData(ResultSet rs) throws SQLException, DataAccessException {
                    if (rs.next()) {
                        UserEntity userEntity = new UserEntity();
                        userEntity.setId(rs.getLong("id"));
                        userEntity.setAge(rs.getInt("age"));
                        userEntity.setClientSn(rs.getLong("clientSn"));
                        userEntity.setSex(rs.getString("sex"));
                        userEntity.setUserName(rs.getString("userName"));

                        return userEntity;
                    }
                    return null;
                }
            });
        }
        return null;
    }
}
